<!-- eslint-disable vue/html-indent -->
<template>
  <view class="mgt1" v-if="data.setList && data.setList.length > 0"
    :style="{ marginBottom: selectedIndexes.length > 0 ? '192rpx' : 0 }">
    <tm-slide-switch v-for="(item, index) in data.setList" :key="item.id" :padding="[32, 20]" :height="116">
      <tm-sheet :margin="[0]">
        <directory-main :key="item.id" :content="item" :index="index" :isShowRight="false" :isSelectMode="isSelectMode"
          :selectedIndexes="selectedIndexes" :enableTouch="true" @btnClick="clickFile"
          @touchEnd="onTouchEnd"></directory-main>
      </tm-sheet>
      <template v-slot:right>
        <view class="flex flex-row flex-row-center-end">
          <tm-sheet _class="flex flex-row flex-row-center-center" :width="120" :height="116" color="red" no-level
            :margin="[0]" :padding="[0]" @click="deleteOpenFile(item as IFile)">
            <tm-text :userInteractionEnabled="false" label="删除"></tm-text>
          </tm-sheet>
        </view>
      </template>
    </tm-slide-switch>
    <view v-if="audioShow" class="tool-bottom" style="height: 228rpx">
      <file-audio :src="audioUrl" :title="audioName" :autoplay="audioShow"></file-audio>
      <view @click="audioShow = false" class="audio-close">x</view>
    </view>
    <view v-if="selectedIndexes.length > 0" class="tool-bottom">
      <tm-grid :col="4" color="#f3f3f3">
        <tm-grid-item :height="192" @click="move">
          <view class="tool-bottom-item">
            <tm-icon name="../../../static/tool/share.svg" :font-size="40"></tm-icon>
          </view>
          <tm-text _class="pt-10" :font-size="20" label="移动"></tm-text>
        </tm-grid-item>
        <tm-grid-item :height="192" @click="commonToggle">
          <view class="tool-bottom-item">
            <tm-icon name="../../../static/tool/star.svg" :font-size="40"></tm-icon>
          </view>
          <tm-text _class="pt-10" :font-size="20" label="设为常用"></tm-text>
        </tm-grid-item>
        <tm-grid-item :height="192" @click="tips">
          <view class="tool-bottom-item">
            <tm-icon name="../../../static/header/download.svg" :font-size="40"></tm-icon>
          </view>
          <tm-text _class="pt-10" :font-size="20" label="下载"></tm-text>
        </tm-grid-item>
        <tm-grid-item :height="192" v-if="selectedIndexes.length <= 1" @click="edit">
          <view class="tool-bottom-item">
            <tm-icon name="../../../static/tool/edit.svg" :font-size="40"></tm-icon>
          </view>
          <tm-text _class="pt-10" :font-size="20" label="编辑"></tm-text>
        </tm-grid-item>
      </tm-grid>
    </view>
  </view>
  <tm-sheet v-else :margin="[0]">
    <tm-result :showBtn="false" subTitle=" " title="暂无数据"></tm-result>
  </tm-sheet>
  <tm-overlay v-model:show="showWin" contentAnimation>
    <view @click.stop>
      <tm-sheet :width="500" :height="200" v-show="currentType == 'delete'">
        <tm-text label="删除方式"></tm-text>
        <tm-divider></tm-divider>
        <view class="flex flex-row flex-wrap" style="justify-content: center">
          <tm-button text outlined :margin="[20]" size="small" label="取消" @click="showWin = false"></tm-button>
          <tm-button :margin="[20]" size="small" label="标记删除" @click="deleteOverlayFile(1)"></tm-button>
          <tm-button :margin="[20]" size="small" color="red" label="彻底删除" @click="deleteOverlayFile(2)"></tm-button>
        </view>
      </tm-sheet>
    </view>
  </tm-overlay>
  <tm-overlay v-model:show="videoType" contenteditable>
    <view @click.stop>
      <tm-sheet :width="500">
        <tm-text :label="videoName"></tm-text>
        <tm-divider></tm-divider>
        <video :key="Date.now()" style="width: 100%" v-if="videoType" :src="videoUrl" id="myVideo" controls="true"
          :vslide-gesture-in-fullscreen="true" show-fullscreen-btn="true" direction="-90" :title="videoName"
          @error="handleVideoError"></video>
      </tm-sheet>
    </view>
  </tm-overlay>
  <tm-drawer ref="calendarView" placement="bottom" v-model:show="moveFileFlag" okText="移动"
    :title="moveFile ? moveFile.name : '移动文件'" :height="1000" @ok="moveFileOk">
    <directoryMove :updateFlag="moveFileFlag" @updateFile="updateMoveFile"></directoryMove>
  </tm-drawer>
  <tm-notification placement="top" ref="msg" label="消息提醒"></tm-notification>
  <CodeViewer v-model:visible="codeViewerVisible" :fileName="codeFileName" :content="codeContent"
    :extension="codeExtension" />
</template>

<script lang="ts" setup>
import CodeViewer from './CodeViewer.vue'
import {
  IDEntity,
  IDirectory,
  IFile,
  ISysFileInfo,
  IWork,
  IWorkTask
} from '@/ts/core'
import { ref, reactive, watch, defineExpose, onMounted, nextTick } from 'vue'
import tmNotification from '@/tmui/components/tm-notification/tm-notification.vue'
import fileAudio from '@/components/Directory/audio.vue'
import directoryMove from '@/components/Directory/directoryMove.vue'
import directoryMain from '@/components/Directory/main.vue'

import orgCtrl from '@/ts/controller'
// import MarkdownIt from 'markdown-it'
type Props = {
  setList: IDEntity[]
  superior?: IDEntity
  superiorType: boolean
  isSelectable: boolean // 外部传入的选择状态
}
const file_url = 'https://assetcloud.zj.gov.cn'
const isUpdating = ref(false)
const currentFile = ref<IFile | undefined>(undefined)
const hardDelete = ref(0)
const showWin = ref(false)
const currentType = ref('')
const videoType = ref(false)
const videoUrl = ref('')
const videoName = ref('')
const videoContext = ref<any>(undefined)
const audioShow = ref(false)
const audioName = ref('')
const audioUrl = ref('')
const isSelectMode = ref(false) // 是否是选择模式
const selectedIndexes = ref<number[]>([]) // 选中的索引
const selectedFiles = ref<IFile[]>([]) // 选中的文件数据
const moveFile = ref<IFile>() // 移动的文件
const msg = ref<InstanceType<typeof tmNotification> | null>(null)
const props = defineProps<Props>()
const moveFileFlag = ref(false)
const codeViewerVisible = ref(false)
const codeFileName = ref('')
const codeContent = ref('')
const codeExtension = ref('')
const emit = defineEmits([
  'changeSuperior',
  'updateSetList',
  'refresh',
  'changeHierarchyName',
  'selectionComplete',
  'changeSelectable'
])
const data = reactive<Props>({
  setList: [...props.setList],
  superior: props.superior ? props.superior : undefined,
  superiorType: props.superiorType,
  isSelectable: props.isSelectable
})
watch(
  () => props.setList,
  newValue => {
    data.setList = [...newValue]
  }
)
watch(
  () => props.superior,
  newValue => {
    data.superior = newValue
  }
)
watch(
  () => props.isSelectable,
  newValue => {
    isSelectMode.value = newValue // 根据外部传入的值来设置选择模式
    if (!isSelectMode.value) {
      // 退出选择模式时清空选择的数据
      clearSelection()
    }
  }
)
/** 文件移动 */
const move = () => {
  //给一个移动的底部弹窗
  moveFileFlag.value = true
}
/** 移动后的当前目录情况 */
const updateMoveFile = (file: IFile) => {
  moveFile.value = file
}
const moveFileOk = () => {
  const entitys = selectedFiles.value //这是一个选择的元素为iFile的数组
  if (!moveFile.value) {
    msg.value?.show({ label: '请选择移动的目录' })
    return false
  }
  entitys.forEach(entity => {
    entity.move(moveFile.value! as IDirectory).then((success: boolean) => {
      if (success) {
        msg.value?.show({ label: '移动成功' })
        directoryRefresh()
      }
      toggleSelectMode()
    })
  })
}
/** 常用标签变更 */
const commonToggle = (isCompany: boolean = false) => {
  const entitys = selectedFiles.value //这是一个选择的元素为iFile的数组
  entitys.forEach(entity => {
    entity.toggleCommon(isCompany).then((success: boolean) => {
      if (success) {
        msg.value?.show({ label: '设置成功' })
        directoryRefresh()
      }
      toggleSelectMode()
    })
  })
}
/** 跳转编辑 */
const edit = () => {
  const entitys = selectedFiles.value //这是一个选择的元素为iFile的数组
  if (entitys.length > 1) {
    msg.value?.show({ label: '只能选择一个文件编辑' })
    return
  }
  const applicationId_common = entitys[0].metadata.applicationId
    ? entitys[0].metadata.applicationId
    : entitys[0].metadata.directoryId
  const applicationId =
    entitys[0].typeName === '应用' || entitys[0].typeName === '目录'
      ? entitys[0].id
      : applicationId_common
  uni.navigateTo({
    url:
      '/pages/edit/edit?id=' +
      entitys[0].id +
      '&belongId=' +
      entitys[0].belongId +
      '&targetId=' +
      entitys[0].target.id +
      '&applicationId=' +
      applicationId +
      `${entitys[0].isVirtual ? '&isVirtual=' + entitys[0].isVirtual : ''}`
  })
}
// 监听长按
const onTouchEnd = () => {
  toggleSelectMode() // 如果长按，切换选择模式
}

// 切换选择模式
const toggleSelectMode = () => {
  if (isSelectMode.value) {
    uni.showTabBar()
    clearSelection()
  } else {
    uni.hideTabBar()
  }
  isSelectMode.value = !isSelectMode.value
  emit('changeSelectable', isSelectMode.value)
}
//清空选择的数据
const clearSelection = () => {
  selectedFiles.value = []
  selectedIndexes.value = []
}
// 选择或取消选择文件
const toggleFileSelection = (index: number, file: any) => {
  if (selectedIndexes.value.includes(index)) {
    selectedIndexes.value = selectedIndexes.value.filter(i => i !== index)
    selectedFiles.value = selectedFiles.value.filter(f => f.id !== file.id)
  } else {
    selectedIndexes.value.push(index)
    selectedFiles.value.push(file)
  }
  emit('selectionComplete', selectedIndexes.value, selectedFiles.value)
}
//视频加载错误重新加载
const handleVideoError = e => {
  console.log('视频加载错误', e)
  const url = videoUrl.value + `?t=${Date.now()}`
  videoUrl.value = url
}
onMounted(() => {
  const shouldCall = uni.getStorageSync('shouldCallMethod')
  if (shouldCall) {
    directoryRefresh()
    uni.removeStorageSync('shouldCallMethod') // 调用后清除标记
  }
  videoContext.value = uni.createVideoContext('myVideo')
})
//删除
const fileDelete = async () => {
  if (!currentFile.value) return
  const success = await (hardDelete.value === 1
    ? currentFile.value.delete()
    : currentFile.value.hardDelete())
  if (success) {
    directoryRefresh()
    orgCtrl.changCallback()
  }
}
//删除弹窗点击按钮
const deleteOverlayFile = (hardType: number) => {
  hardDelete.value = hardType
  fileDelete()
  showWin.value = false
}
const directoryRefresh = () => {
  if (data.superior) {
    goData(data.superior, true)
  } else {
    if ('superior' in data.setList[0]) {
      emit('refresh', data.setList[0].superior.directory, 'disk', true)
    }
  }
}
const filesMenu = (firstMenuItem: string, secondMenuItem?: string) => {
  if (firstMenuItem === '刷新目录') {
    directoryRefresh()
  }
}
//删除弹窗
const deleteOpenFile = (file: IFile) => {
  currentFile.value = file
  showWin.value = true
  currentType.value = 'delete'
}
defineExpose({ filesMenu })
const clickFile = (item: any, index: number, _type: string) => {
  if (isSelectMode.value) {
    toggleFileSelection(index, item)
  } else {
    goData(item)
  }
}
const openEntityFile = (file: IFile) => {
  //实体文件打开
  const data: any = 'size' in file ? file : (file as ISysFileInfo).filedata
  const officeExt = ['.pdf', '.xls', '.xlsx', '.doc', '.docx', '.ppt', '.pptx']
  const videoExt = ['.mp4', '.avi', '.mov', '.mpg', '.swf', '.flv', '.mpeg']
  const codeExt = [
    '.vue',
    '.tsx',
    '.jsx',
    '.js',
    '.json',
    '.html',
    '.java',
    '.ts',
    '.css',
    '.scss',
    '.md'
  ]
  const audioExt = ['.mp3', '.wav', '.ogg']
  const isVideo =
    data.contentType?.startsWith('video') ||
    videoExt.includes(data.extension ?? '-')
  const isAudio =
    data.contentType?.startsWith('audio') ||
    audioExt.includes(data.extension ?? '-')
  const isDcm = data.extension === '.dcm'

  if (officeExt.includes(data.extension ?? '-')) {
    uni.downloadFile({
      url: file_url + data.shareLink,
      success: function (res) {
        const filePath = res.tempFilePath
        uni.openDocument({
          filePath: filePath,
          showMenu: true,
          success: function () {
            uni.hideLoading()
          }
        })
      },
      complete: function () {
        uni.hideLoading()
      }
    })
  }
  if (data.contentType?.startsWith('image')) {
    uni.previewImage({
      urls: [file_url + data.shareLink],
      showmenu: true,
      success: function () {
        uni.hideLoading()
      }
    })
  }
  if (isVideo) {
    videoType.value = true
    videoName.value = data.name
    videoUrl.value = file_url + data.shareLink
  }
  if (codeExt.includes(data.extension ?? '-')) {
    uni.showLoading({ title: '加载代码...' })
    uni.request({
      url: file_url + data.shareLink,
      method: 'GET',
      dataType: 'text', // 确保以文本形式获取
      success: res => {
        if (res.statusCode === 200 && typeof res.data === 'string') {
          codeFileName.value = data.name
          codeContent.value = res.data
          codeExtension.value = data.extension ?? ''
          codeViewerVisible.value = true // 显示 CodeViewer
        } else {
          console.error('请求代码文件失败', res)
          msg.value?.show({ label: '加载代码文件失败' })
        }
      },
      fail: err => {
        console.error('请求代码文件错误', err)
        msg.value?.show({ label: '加载代码文件出错' })
      },
      complete: () => {
        uni.hideLoading()
      }
    })
    return
  }
  if (isAudio) {
    audioUrl.value = file_url + data.shareLink
    audioName.value = data.name
    audioShow.value = true
  }
  if (isDcm) {
    //还没做
    tips()
  }
}
const openPlatformFile = async (file: IFile) => {
  //平台文件打开
  const data = file.typeName
  //平台文件类型：模块、表单、报表、视图、迁移配置、页面模板、数据模板、商城模板、空间模板、任务、分发任务、报表树、打印模板、办事、集群模板、加用户、子流程、事项、物详情、引用型、属性、字典、分类
  if (data === '办事') {
    const fileData = await (file as IWork | IWorkTask).createApply(
      undefined,
      undefined
    )
    if (fileData?.applyType === '列表') {
      uni.navigateTo({
        url:
          '/pages/open/workList?id=' +
          file.id +
          '&belongId=' +
          file.belongId +
          '&targetId=' +
          file.target.id
      })
    } else {
      uni.navigateTo({
        url:
          '/pages/open/work?id=' +
          file.id +
          '&belongId=' +
          file.belongId +
          '&targetId=' +
          file.target.id
      })
    }
  } else if (data === '表单') {
    uni.navigateTo({
      url: '/pages/open/form?id=',
      success: function (res) {
        res.eventChannel.emit('formData', {
          data: file
        })
      }
    })
  } else {
    tips()
  }
}
const goData = async (file: IFile | undefined, isReload: boolean = false) => {
  if (isUpdating.value) return // 检查标志
  isUpdating.value = true // 设置为正在更新
  uni.showLoading({ title: '加载中...' })
  // 防止重复设置焦点
  if (file && file.key) {
    if ('isContainer' in file && file.isContainer) {
      try {
        file?.loadContent(isReload).then(() => {
          data.superiorType = false
          data.superior = file
          emit('updateSetList', file?.content())
          emit('changeSuperior', data.superior)
          emit('changeHierarchyName', file.name)
        })
      } catch (error) {
        console.error('加载内容失败', error)
      }
    } else if ('size' in file || 'filedata' in file) {
      openEntityFile(file)
    } else if ('key' in file) {
      openPlatformFile(file)
    }
  }
  uni.hideLoading()
  isUpdating.value = false // 更新结束
}
const tips = () => {
  nextTick(() => {
    msg.value?.show({ label: '等待开发中' })
  })
}
</script>

<style lang="scss">
@import '../../common/style/global.scss';

.tool-bottom {
  width: 100%;
  height: 192rpx;
  position: fixed;
  bottom: 0;
  left: 0;
  background-color: #f3f3f3;

  .tool-bottom-item {
    width: 80rpx;
    height: 80rpx;
    background-color: #fff;
    border-radius: 10rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 6rpx;
  }

  .audio-close {
    position: absolute;
    top: -20rpx;
    right: 0;
    width: 40rpx;
    height: 40rpx;
    background-color: #000;
    color: white;
    border-radius: 50%;
    line-height: 40rpx;
    text-align: center;
  }
}
</style>
@/ts/core